﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Ruanmou.Framework.MapperHelper
{
    public class ExpressionMapper<Tin,Tout>
    {
        /// <summary>
        /// 泛型缓存
        /// </summary>
        private static Func<Tin, Tout> _Func = null;

        static ExpressionMapper()
        {
            ParameterExpression parameterExpression = Expression.Parameter(typeof(Tin), "p");

            List<MemberBinding> memberBindingsList = new List<MemberBinding>();
            foreach (var item in typeof(Tout).GetProperties())
            {
                MemberExpression property = Expression.Property(parameterExpression, typeof(Tin).GetProperty(item.Name));
                MemberBinding memberBinding = Expression.Bind(item, property);
                memberBindingsList.Add(memberBinding);
            }

            foreach (var item in typeof(Tout).GetFields())
            {
                MemberExpression property = Expression.Field(parameterExpression, typeof(Tin).GetField(item.Name));

                MemberBinding memberBinding = Expression.Bind(item, property);
                memberBindingsList.Add(memberBinding);
            }

            MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(Tout)), memberBindingsList.ToArray());
            Expression<Func<Tin, Tout>> lambda = Expression.Lambda<Func<Tin, Tout>>(memberInitExpression, new ParameterExpression[] { parameterExpression });
            _Func = lambda.Compile();
        }




        public static Tout  Trans(Tin instance)
        {
            if (_Func != null)
            {
               return _Func(instance);
            }
            return default(Tout);
        }

    }
}
